#include "StdAfx.h"
/// Copyright 2012, Alex Averian, Yonan Research
/// Released under BSD Licence




#include "..\qcom.h"
using namespace micro::com;


#include "qdirect2d.h"
using namespace micro::directx;



//
// Creates a QDirect2D bitmap from the specified
// file name.
//
HRESULT QDirect2D::LoadBitmapFromFile(
    ID2D1RenderTarget * renderTarget,    LPCTSTR path,
    unsigned int destinationWidth,    unsigned int destinationHeight,
    ID2D1Bitmap ** bitmap
)
{
    QComPointer<IWICBitmapSource> bitmapSource;
    RINOK( QWic::CreateBitmapSourceFromFile( path, destinationWidth, destinationHeight, &bitmapSource ) );

    // Create a QDirect2D bitmap from the WIC bitmap.
    RINOK( renderTarget->CreateBitmapFromWicBitmap( bitmapSource, nullptr, bitmap ) );

    return S_OK;
}


//
// Creates a QDirect2D bitmap from the specified
// resource name and type.
//
HRESULT QDirect2D::LoadBitmapFromResource(
    ID2D1RenderTarget * renderTarget,
    LPCTSTR resourceName,    LPCTSTR resourceType,
    unsigned int destinationWidth,    unsigned int destinationHeight,
    ID2D1Bitmap ** bitmap
)
{
    QComPointer<IWICImagingFactory> wicFactory;
    QComPointer<IWICBitmapSource> bitmapSource;
    RINOK( QWic::CreateBitmapSourceFromResource( resourceName, resourceType,  destinationWidth, destinationHeight, &bitmapSource ) );

    // Create a QDirect2D bitmap from the WIC bitmap.
    RINOK( renderTarget->CreateBitmapFromWicBitmap( bitmapSource, nullptr, bitmap ) );

    return S_OK;
}


//
// Create a QDirect2D Bitmap from a Shell Thumbnail cache
//
// HRESULT QDirect2D::DecodeImageFromThumbCache(
//     IShellItem* shellItem,
//     ID2D1RenderTarget* renderTarget,
//     unsigned int thumbnailSize,
//     ID2D1Bitmap** bitmap
// )
// {
//     HRESULT hr = S_OK;
//
//     QComPointer<IShellItemImageFactory> imageFactory;
//     QComPointer<IWICFormatConverter> converter;
//
//     hr = shellItem->QueryInterface( IID_PPV_ARGS( &imageFactory ) );
//
//     HBITMAP hBitmap = nullptr;
//
//     if ( SUCCEEDED( hr ) )
//     {
//         SIZE size = {thumbnailSize, thumbnailSize};
//         hr = imageFactory->GetImage(
//                  size,
//                  SIIGBF_BIGGERSIZEOK, // improves performance, since we'll need to resize anyway
//                  &hBitmap
//              );
//     }
//
//     hr = nullptr == hBitmap ? E_FAIL : hr;
//
//     QComPointer<IWICImagingFactory> wicFactory;
//
//     if ( SUCCEEDED( hr ) )
//     {
//         hr = QWic::GetWICFactory( &wicFactory );
//     }
//
//     QComPointer<IWICBitmap> wicBitmap;
//
//     if ( SUCCEEDED( hr ) )
//     {
//         hr = wicFactory->CreateBitmapFromHBITMAP(
//                  hBitmap,
//                  nullptr,
//                  WICBitmapUseAlpha,
//                  &wicBitmap
//              );
//     }
//
//     // Make sure to free the resource as soon as it's not needed.
//     if ( nullptr != hBitmap )
//     {
//         ::DeleteObject( hBitmap );
//         hBitmap = nullptr;
//     }
//
//     if ( SUCCEEDED( hr ) )
//     {
//         // Convert the image format to 32bppPBGRA
//         // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
//         hr = wicFactory->CreateFormatConverter( &converter );
//     }
//
//     if ( SUCCEEDED( hr ) )
//     {
//         hr = converter->Initialize(
//                  wicBitmap,
//                  GUID_WICPixelFormat32bppPBGRA,
//                  WICBitmapDitherTypeNone,
//                  nullptr,
//                  0.f,
//                  WICBitmapPaletteTypeMedianCut
//              );
//     }
//
//     if ( SUCCEEDED( hr ) )
//     {
//         // Create a D2D bitmap from the WIC bitmap
//         hr = renderTarget->CreateBitmapFromWicBitmap(
//                  converter,
//                  nullptr,
//                  bitmap
//              );
//     }
//
//     return hr;
// }

//
// Get a QDirect2D factory
// odata pornita fabrica, ramane pornita
// pana la inchiderea programului
HRESULT QDirect2D::GetGlobalFactory( ID2D1Factory ** factory )
{
    if ( nullptr == factory )
        return E_POINTER;


    static QComPointer<ID2D1Factory> m_pD2DFactory;
    HRESULT hr = S_OK;

    if ( nullptr == m_pD2DFactory )
    {
#if defined(DEBUG) || defined(_DEBUG)
        D2D1_FACTORY_OPTIONS options;
        options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;

        hr = D2D1CreateFactory(
                 D2D1_FACTORY_TYPE_SINGLE_THREADED,
                 //D2D1_FACTORY_TYPE_MULTI_THREADED,
                 options,
                 &m_pD2DFactory
             );
#else
        hr = D2D1CreateFactory(
                 D2D1_FACTORY_TYPE_SINGLE_THREADED,
                 //D2D1_FACTORY_TYPE_MULTI_THREADED,
                 &m_pD2DFactory
             );
#endif
    }

    if ( SUCCEEDED( hr ) )
    {
        hr = m_pD2DFactory.QueryInterface( IID_PPV_ARGS( factory ) );
    }

    return hr;
}

//
// Get a QDirect2D factory
// odata pornita fabrica, ramane pornita
// pana la release,  utila in aplicatii cu DX sporadic
HRESULT QDirect2D::GetLocalFactory( ID2D1Factory ** factory )
{
    if ( nullptr == factory )
        return E_POINTER;

    HRESULT hr = S_OK;

#if defined(DEBUG) || defined(_DEBUG)
    D2D1_FACTORY_OPTIONS options;
    options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;

    hr = D2D1CreateFactory(
             D2D1_FACTORY_TYPE_SINGLE_THREADED,
             //D2D1_FACTORY_TYPE_MULTI_THREADED,
             options,
             factory
         );
#else
    hr = D2D1CreateFactory(
             D2D1_FACTORY_TYPE_SINGLE_THREADED,
             //D2D1_FACTORY_TYPE_MULTI_THREADED,
             factory
         );
#endif


    return hr;
}

//
// Create a QDirect2D Bitmap from a Shell Thumbnail cache
//
// HRESULT QDirect2D::DecodeImageFromThumbCache(
//     IShellItem* shellItem,
//     ID2D1RenderTarget* renderTarget,
//     unsigned int thumbnailSize,
//     ID2D1Bitmap** bitmap
// )
// {
//     HRESULT hr = S_OK;
//
//     QComPointer<IShellItemImageFactory> imageFactory;
//     QComPointer<IWICFormatConverter> converter;
//
//     hr = shellItem->QueryInterface( IID_PPV_ARGS( &imageFactory ) );
//
//     HBITMAP hBitmap = nullptr;
//
//     if ( SUCCEEDED( hr ) )
//     {
//         SIZE size = {thumbnailSize, thumbnailSize};
//         hr = imageFactory->GetImage(
//                  size,
//                  SIIGBF_BIGGERSIZEOK, // improves performance, since we'll need to resize anyway
//                  &hBitmap
//              );
//     }
//
//     hr = nullptr == hBitmap ? E_FAIL : hr;
//
//     QComPointer<IWICImagingFactory> wicFactory;
//
//     if ( SUCCEEDED( hr ) )
//     {
//         hr = GetWICFactory( &wicFactory );
//     }
//
//     QComPointer<IWICBitmap> wicBitmap;
//
//     if ( SUCCEEDED( hr ) )
//     {
//         hr = wicFactory->CreateBitmapFromHBITMAP(
//                  hBitmap,
//                  nullptr,
//                  WICBitmapUseAlpha,
//                  &wicBitmap
//              );
//     }
//
//     // Make sure to free the resource as soon as it's not needed.
//     if ( nullptr != hBitmap )
//     {
//         ::DeleteObject( hBitmap );
//         hBitmap = nullptr;
//     }
//
//     if ( SUCCEEDED( hr ) )
//     {
//         // Convert the image format to 32bppPBGRA
//         // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
//         hr = wicFactory->CreateFormatConverter( &converter );
//     }
//
//     if ( SUCCEEDED( hr ) )
//     {
//         hr = converter->Initialize(
//                  wicBitmap,
//                  GUID_WICPixelFormat32bppPBGRA,
//                  WICBitmapDitherTypeNone,
//                  nullptr,
//                  0.f,
//                  WICBitmapPaletteTypeMedianCut
//              );
//     }
//
//     if ( SUCCEEDED( hr ) )
//     {
//         // Create a D2D bitmap from the WIC bitmap
//         hr = renderTarget->CreateBitmapFromWicBitmap(
//                  converter,
//                  nullptr,
//                  bitmap
//              );
//     }
//
//     return hr;
// }



